package MountainMq.task;


import MountainMq.po.TransMessagePO;
import MountainMq.service.TransMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

@EnableScheduling
@Configuration
@Component
@Slf4j
public class ResendTask {
    @Autowired
    private TransMessageService transMessageService;
    @Autowired(required = false)
    private RabbitTemplate rabbitTemplate;
    @Value("${mountainmq.resendTimes}")
    public Integer resendTimes;

    // 重发频率
    @Scheduled(fixedDelayString = "${mountainmq.resendFreq}")
    public void resendMessage(){
        log.info("resendMessage() invoke.");
        // 查询出所有应发未发的消息
        List<TransMessagePO> messagePOS = transMessageService.listReadyMessages();
        log.info("resendMessage():messagepos:{}",messagePOS);
        for (TransMessagePO po : messagePOS) {
            log.info("resendMessage():PO:{}",po);
            if(po.getSequence() >= resendTimes){ // 冲出
                log.error("resend too many times! resendTimes:{}!",resendTimes);
                transMessageService.messageDead(po.getId());
                continue;
            }
            MessageProperties messageProperties = new MessageProperties();
            messageProperties.setContentType("application/json");
            Message message = new Message(po.getPayload().getBytes(),messageProperties);
            // 给消息本身也设置ID，因为在消息返回机制中，是没有correlationData参数的，那么就无法确认消息是谁了
            message.getMessageProperties().setMessageId(po.getId());

            // 消息标识 通过这个数据我们就可以知道这些消息对应数据库中的ID，便于区分 用于消息确认回调
            CorrelationData correlationData = new CorrelationData(po.getId());
            // 发消息
            rabbitTemplate.convertAndSend(po.getExchange(),po.getRoutingKey()
                    ,message,correlationData);
            log.info("message sent,ID:{}",po.getId());
            // 增加发送次数
            transMessageService.messageResend(po.getId());
        }
    }
}
